using UnityEngine;
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;

#if UNITY_ANDROID && !UNITY_EDITOR
using UnityEngine.Android;
#endif

namespace Galplay {
  public class ProjectManager {
    public static string[] WIN_PATH = new string[] { "H:\\Galplay" };
    public static string[] ANDROID_PATH = new string[] { "Galplay" };

    public static string GetDownloadPath(string inner_path = "") {
#if UNITY_ANDROID && !UNITY_EDITOR
        // 获取Android的Context对象
        using (AndroidJavaClass environment = new AndroidJavaClass("android.os.Environment"))
        {
            // 获取Download目录
            using (AndroidJavaObject downloadDir = environment.CallStatic<AndroidJavaObject>("getExternalStoragePublicDirectory",
                environment.GetStatic<string>("DIRECTORY_DOWNLOADS")))
            {
                return Path.Combine(downloadDir.Call<string>("getAbsolutePath"), inner_path);
            }
        }
#else
      // 非Android平台返回persistentDataPath
      return Path.Combine(Application.persistentDataPath, inner_path);
#endif
    }

    private static ProjectManager _instance;

    public static ProjectManager Instance {
      get {
        _instance ??= new ProjectManager();
        return _instance;
      }
    }

    private ProjectManager() {

      // 如果Android，扫描Download
#if UNITY_ANDROID && !UNITY_EDITOR
      // 依次扫描项目
      foreach (var i in ANDROID_PATH) {
        Scan(GetDownloadPath(i));
      }
#else
      // 依次扫描项目
      foreach (var i in WIN_PATH) {
        Scan(i);
      }
#endif

      // 获得第一个项目
      if (Games.Count >= 1) {
        Current = Games[0];
      }
      if (Games.Count >= 2) {
        Current = Games[1];
      }
    }

    public List<GameProject> Games { get; private set; } = new List<GameProject>();
    public GameProject Current { get; private set; }

    internal void SetGame(GameProject game) {
      Current = game;
    }

    private void Scan(string path) {
      // 验证目录存在
      if (!Directory.Exists(path)) {
        Debuger.LogError($"Path not exist: {path}");
        return;
      }


      try {
        // 扫描直接子目录（不递归）
        foreach (var directoryPath in Directory.EnumerateDirectories(path)) {
          Games.Add(new GameProject(directoryPath));
        }

        // 扫描直接文件（不递归）
        foreach (var filePath in Directory.EnumerateFiles(path, "*.zip")) {
          Games.Add(new GameProject(filePath));
        }
      } catch (UnauthorizedAccessException ex) {
        Debuger.LogError($"Access denied to path: {ex.Message}");
      } catch (PathTooLongException ex) {
        Debuger.LogError($"Path too long: {ex.Message}");
      } catch (IOException ex) {
        Debuger.LogError($"IO error occurred: {ex.Message}");
      } catch (Exception ex) {
        Debuger.LogError($"Error: {ex.Message}");
      }
    }

    public static IEnumerable<string> ScanFiles(string path, string ext) {
      // 参数验证
      if (string.IsNullOrWhiteSpace(path) || string.IsNullOrWhiteSpace(ext)) {
        Debuger.LogError("Path or Extension cannot be null or empty");
        return Enumerable.Empty<string>();
      }

      // 验证目录存在
      if (!Directory.Exists(path)) {
        Debuger.LogError($"Path not exist: {path}");
        return Enumerable.Empty<string>();
      }

      try {
        // 使用yield return实现延迟加载
        // 确保路径以目录分隔符结尾，便于后续处理
        var normalizedPath = path.EndsWith(Path.DirectorySeparatorChar.ToString())
            ? path
            : path + Path.DirectorySeparatorChar;

        // 获取文件并转换为相对路径
        return Directory.EnumerateFiles(path, $"*.{ext.TrimStart('.')}", SearchOption.TopDirectoryOnly)
                       .Select(fullPath => {
                         // 转换为相对路径
                         var relativePath = fullPath.Substring(normalizedPath.Length);
                         return relativePath;
                       });
      } catch (UnauthorizedAccessException ex) {
        Debuger.LogError($"Access denied: {ex.Message}");
      } catch (PathTooLongException ex) {
        Debuger.LogError($"Path too long: {ex.Message}");
      } catch (Exception ex) {
        Debuger.LogError($"Error scanning files: {ex.Message}");
      }

      return Enumerable.Empty<string>();
    }

  }

}